package com.wmx.guava;

import com.google.common.collect.Lists;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * CartesianList是Guava中用于计算多个集合笛卡尔积的工具类。它提供了一种声明式的方式来生成所有可能的组合，无需编写嵌套循环。
 *
 * @author wangMaoXiong
 * @version 1.0
 * @date 2025/11/16 上午10:18
 */
public class CartesianListTest {

    /**
     * List<List<B>> cartesianProduct(List<? extends B>... lists)
     * List<List<B>> cartesianProduct(List<? extends List<? extends B>> lists)
     * 1、对每个集合元素求笛卡儿积
     * 2、返回的List实际是 CartesianList 对象
     * 3、返回的结果内容是不可变的，不能直接修改，否则报错 java.lang.UnsupportedOperationException
     * 4、它们顶层使用的是 CartesianList.create，但是这个类无法外部直接访问。
     * */
    @Test
    public void test() {
        List<String> colors = Arrays.asList("红", "蓝");
        List<String> sizes = Arrays.asList("大", "小");
        List<String> materials = Arrays.asList("棉", "丝");

        List<List<String>> combinations = Lists.cartesianProduct(colors, sizes, materials);
        // 结果：2 * 2 * 2 = 8 种组合
        // [
        // [红, 大, 棉],
        // [红, 大, 丝],
        // [红, 小, 棉],
        // [红, 小, 丝],
        // [蓝, 大, 棉],
        // [蓝, 大, 丝],
        // [蓝, 小, 棉],
        // [蓝, 小, 丝]
        // ]
        System.out.println(combinations);
    }

    @Test
    public void test1() {
        List<List<String>> dimensions = Arrays.asList(
                Arrays.asList("红", "蓝"),          // 颜色
                Arrays.asList("大", "中", "小"),    // 尺寸
                Arrays.asList("棉", "丝")           // 材质
        );
        List<List<String>> combinations = Lists.cartesianProduct(dimensions);
        // 结果：2 * 3 * 2 = 12种组合
        // [[红, 大, 棉], [红, 大, 丝], [红, 中, 棉], [红, 中, 丝], [红, 小, 棉], [红, 小, 丝], [蓝, 大, 棉], [蓝, 大, 丝], [蓝, 中, 棉], [蓝, 中, 丝], [蓝, 小, 棉], [蓝, 小, 丝]]
        System.out.println(combinations);
    }


    @Test
    public void test2() {
        ArrayList list1 = new ArrayList();
        list1.add(1);
        list1.add(2);

        ArrayList list2 = new ArrayList();
        list2.add("1");
        list2.add("2");

        ArrayList list3 = new ArrayList();
        list3.add("1");
        list3.add("2");
        list3.add("3");

        ArrayList list4 = new ArrayList();
        list4.add("1");

        ArrayList allList = new ArrayList();
        allList.add(list1);
        allList.add(list2);
        allList.add(list3);
        allList.add(list4);

        List<List<Object>> combinations = Lists.cartesianProduct(allList);
        // 结果：2 * 2 * 3 * 1= 12 种组合
        // [
        // [1, 1, 1, 1],
        // [1, 1, 2, 1],
        // [1, 1, 3, 1],
        // [1, 2, 1, 1],
        // [1, 2, 2, 1],
        // [1, 2, 3, 1],
        // [2, 1, 1, 1],
        // [2, 1, 2, 1],
        // [2, 1, 3, 1],
        // [2, 2, 1, 1],
        // [2, 2, 2, 1],
        // [2, 2, 3, 1]
        // ]
        System.out.println(combinations);
    }

    @Test
    public void test3(){
        List<List<String>> combinations = Lists.cartesianProduct(
                Arrays.asList("A", "B"),
                Arrays.asList("1", "2")
        );

        // CartesianList是懒加载的，只有在访问时才计算
        System.out.println(combinations.get(0)); // 第一次访问时计算 [A, 1]

        // 支持大小查询
        System.out.println(combinations.size()); // 4
    }

}
